home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- void colormapped_blit(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, RECT *srcrect, char *colormap)
- {
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(colormap != 0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(srcrect, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get pointers
-
- d = (BYTE *)destsurf.lpSurface;
- s = (BYTE *)srcsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- int line_offset_src = srcsurf.lPitch - w,
- line_offset_dest = destsurf.lPitch - w;
-
- // Do the blit
-
- __asm
- {
- mov ebx, colormap
-
- mov esi, s
- mov edi, d
-
- // Make sure high order of eax is clear
-
- xor eax, eax
-
- mov edx, h
- blit_loop_y:
-
- mov ecx, w
- blit_loop_x:
-
- // Get source pixel shift it 8 bits to the left and add destination pixel
-
- lodsb
- shl ax, 8
- add al, [edi]
-
- // Lookup value from table and store it
-
- mov al, [ebx + eax]
- stosb
-
- loop blit_loop_x
-
- // Goto next line
-
- add esi, line_offset_src
- add edi, line_offset_dest
-
- dec edx
- jnz blit_loop_y
- }
-
- // Unlock surfaces
-
- src->Unlock(srcrect);
- dest->Unlock(destrect);
- }
-
- void rotated_blit(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, int mx, int my, fix angle, fix scale)
- {
- // Define: (x,y) is a point in the source surface,
- // (u,v) is a point in the destination surface,
- // (0,0) corresponds to the center of the image in both surfaces.
- //
- // A point in the source surface is then given as:
- //
- // (x,y) = 1/scale * ((cos angle, sin angle), (-sin angle, cos angle)) (u,v)
-
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(scale != (fix)0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(0, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get destination pointer
-
- d = (BYTE *)destsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- // Compute some frequently used variables
-
- fix cos_angle_over_scale = cos(angle) / scale,
- sin_angle_over_scale = sin(angle) / scale;
-
- // Compute (dx,dy) for (du,dv)=(1,0)
-
- #define dx_du cos_angle_over_scale
- #define dy_du -sin_angle_over_scale
-
- // Compute (dx,dy) for (du,dv)=(0,1)
-
- #define dx_dv sin_angle_over_scale
- #define dy_dv cos_angle_over_scale
-
- // Compute the first pixel in the destination surface (su, sv)
-
- int su = destrect->left - mx,
- sv = destrect->top - my;
-
- // Compute the first pixel in the source surface (sx, sy)
-
- fix sx = cos_angle_over_scale * su + sin_angle_over_scale * sv,
- sy = cos_angle_over_scale * sv - sin_angle_over_scale * su;
-
- // Transform to the source surface coordinates
-
- sx += srcsurf.dwWidth / 2;
- sy += srcsurf.dwHeight / 2;
-
- // Do the blit
-
- for (int v = 0; v < h; v++)
- {
- // (x,y) is the current pixel that has to be copied
-
- fix x = sx,
- y = sy;
-
- for (int u = 0; u < w; u++, d++)
- {
- // (ix,iy) is the integer location of the current pixel
-
- int ix = (int)x, iy = (int)y;
-
- // Check if (ix,iy) is in the image
-
- if (ix >= 0 && ix < (int)srcsurf.dwWidth && iy >= 0 && iy < (int)srcsurf.dwHeight)
- {
- // Compute the pixels location in memory
-
- s = ((BYTE *)srcsurf.lpSurface) + iy * srcsurf.lPitch + ix;
-
- // If not mask_color then write the pixel
-
- if (*s != mask_color)
- *d = *s;
- }
-
- // Update (x,y)
-
- x += dx_du;
- y += dy_du;
- }
-
- // Update the destination pointer to the next scanline
-
- d += destsurf.lPitch - w;
-
- // (sx,sy) is moved one scanline
-
- sx += dx_dv;
- sy += dy_dv;
- }
-
- // Unlock surfaces
-
- src->Unlock(0);
- dest->Unlock(destrect);
- }
-
- void rotated_colormapped_blit(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, int mx, int my, fix angle, fix scale, char *colormap)
- {
- // Define: (x,y) is a point in the source surface,
- // (u,v) is a point in the destination surface,
- // (0,0) corresponds to the center of the image in both surfaces.
- //
- // A point in the source surface is then given as:
- //
- // (x,y) = 1/scale * ((cos angle, sin angle), (-sin angle, cos angle)) (u,v)
-
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(colormap != 0 && scale != (fix)0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(0, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get destination pointer
-
- d = (BYTE *)destsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- // Compute some frequently used variables
-
- fix cos_angle_over_scale = cos(angle) / scale,
- sin_angle_over_scale = sin(angle) / scale;
-
- // Compute (dx,dy) for (du,dv)=(1,0)
-
- #define dx_du cos_angle_over_scale
- #define dy_du -sin_angle_over_scale
-
- // Compute (dx,dy) for (du,dv)=(0,1)
-
- #define dx_dv sin_angle_over_scale
- #define dy_dv cos_angle_over_scale
-
- // Compute the first pixel in the destination surface (su, sv)
-
- int su = destrect->left - mx,
- sv = destrect->top - my;
-
- // Compute the first pixel in the source surface (sx, sy)
-
- fix sx = cos_angle_over_scale * su + sin_angle_over_scale * sv,
- sy = cos_angle_over_scale * sv - sin_angle_over_scale * su;
-
- // Transform to the source surface coordinates
-
- sx += srcsurf.dwWidth / 2;
- sy += srcsurf.dwHeight / 2;
-
- // Do the blit
-
- for (int v = 0; v < h; v++)
- {
- // (x,y) is the current pixel that has to be copied
-
- fix x = sx,
- y = sy;
-
- for (int u = 0; u < w; u++, d++)
- {
- // (ix,iy) is the integer location of the current pixel
-
- int ix = (int)x, iy = (int)y;
-
- // Check if (ix,iy) is in the image
-
- if (ix >= 0 && ix < (int)srcsurf.dwWidth && iy >= 0 && iy < (int)srcsurf.dwHeight)
- {
- // Compute the pixels location in memory
-
- s = ((BYTE *)srcsurf.lpSurface) + iy * srcsurf.lPitch + ix;
-
- // Write the pixel
-
- *d = colormap[*d + (*s << 8)];
- }
-
- // Update (x,y)
-
- x += dx_du;
- y += dy_du;
- }
-
- // Update the destination pointer to the next scanline
-
- d += destsurf.lPitch - w;
-
- // (sx,sy) is moved one scanline
-
- sx += dx_dv;
- sy += dy_dv;
- }
-
- // Unlock surfaces
-
- src->Unlock(0);
- dest->Unlock(destrect);
- }
-
- void rotated_blit16(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, int mx, int my, fix angle, fix scale)
- {
- // Define: (x,y) is a point in the source surface,
- // (u,v) is a point in the destination surface,
- // (0,0) corresponds to the center of the image in both surfaces.
- //
- // A point in the source surface is then given as:
- //
- // (x,y) = 1/scale * ((cos angle, sin angle), (-sin angle, cos angle)) (u,v)
-
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(scale != (fix)0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(0, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get destination pointer
-
- d = (BYTE *)destsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- // Compute some frequently used variables
-
- fix cos_angle_over_scale = cos(angle) / scale,
- sin_angle_over_scale = sin(angle) / scale;
-
- // Compute (dx,dy) for (du,dv)=(1,0)
-
- #define dx_du cos_angle_over_scale
- #define dy_du -sin_angle_over_scale
-
- // Compute (dx,dy) for (du,dv)=(0,1)
-
- #define dx_dv sin_angle_over_scale
- #define dy_dv cos_angle_over_scale
-
- // Compute the first pixel in the destination surface (su, sv)
-
- int su = destrect->left - mx,
- sv = destrect->top - my;
-
- // Compute the first pixel in the source surface (sx, sy)
-
- fix sx = cos_angle_over_scale * su + sin_angle_over_scale * sv,
- sy = cos_angle_over_scale * sv - sin_angle_over_scale * su;
-
- // Transform to the source surface coordinates
-
- sx += srcsurf.dwWidth / 2;
- sy += srcsurf.dwHeight / 2;
-
- // Do the blit
-
- for (int v = 0; v < h; v++)
- {
- // (x,y) is the current pixel that has to be copied
-
- fix x = sx,
- y = sy;
-
- for (int u = 0; u < w; u++, d += 2)
- {
- // (ix,iy) is the integer location of the current pixel
-
- int ix = (int)x, iy = (int)y;
-
- // Check if (ix,iy) is in the image
-
- if (ix >= 0 && ix < (int)srcsurf.dwWidth && iy >= 0 && iy < (int)srcsurf.dwHeight)
- {
- // Compute the pixels location in memory
-
- s = ((BYTE *)srcsurf.lpSurface) + iy * srcsurf.lPitch + (ix << 1);
-
- // If not mask_color then write the pixel
-
- if (*(WORD *)s != (WORD)mask_color)
- *(WORD *)d = *(WORD *)s;
- }
-
- // Update (x,y)
-
- x += dx_du;
- y += dy_du;
- }
-
- // Update the destination pointer to the next scanline
-
- d += destsurf.lPitch - (w << 1);
-
- // (sx,sy) is moved one scanline
-
- sx += dx_dv;
- sy += dy_dv;
- }
-
- // Unlock surfaces
-
- src->Unlock(0);
- dest->Unlock(destrect);
- }
-
- void rotated_blit24(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, int mx, int my, fix angle, fix scale)
- {
- // Define: (x,y) is a point in the source surface,
- // (u,v) is a point in the destination surface,
- // (0,0) corresponds to the center of the image in both surfaces.
- //
- // A point in the source surface is then given as:
- //
- // (x,y) = 1/scale * ((cos angle, sin angle), (-sin angle, cos angle)) (u,v)
-
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(scale != (fix)0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(0, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get destination pointer
-
- d = (BYTE *)destsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- // Compute some frequently used variables
-
- fix cos_angle_over_scale = cos(angle) / scale,
- sin_angle_over_scale = sin(angle) / scale;
-
- // Compute (dx,dy) for (du,dv)=(1,0)
-
- #define dx_du cos_angle_over_scale
- #define dy_du -sin_angle_over_scale
-
- // Compute (dx,dy) for (du,dv)=(0,1)
-
- #define dx_dv sin_angle_over_scale
- #define dy_dv cos_angle_over_scale
-
- // Compute the first pixel in the destination surface (su, sv)
-
- int su = destrect->left - mx,
- sv = destrect->top - my;
-
- // Compute the first pixel in the source surface (sx, sy)
-
- fix sx = cos_angle_over_scale * su + sin_angle_over_scale * sv,
- sy = cos_angle_over_scale * sv - sin_angle_over_scale * su;
-
- // Transform to the source surface coordinates
-
- sx += srcsurf.dwWidth / 2;
- sy += srcsurf.dwHeight / 2;
-
- // Do the blit
-
- for (int v = 0; v < h; v++)
- {
- // (x,y) is the current pixel that has to be copied
-
- fix x = sx,
- y = sy;
-
- for (int u = 0; u < w; u++, d += 3)
- {
- // (ix,iy) is the integer location of the current pixel
-
- int ix = (int)x, iy = (int)y;
-
- // Check if (ix,iy) is in the image
-
- if (ix >= 0 && ix < (int)srcsurf.dwWidth && iy >= 0 && iy < (int)srcsurf.dwHeight)
- {
- // Compute the pixels location in memory
-
- s = ((BYTE *)srcsurf.lpSurface) + iy * srcsurf.lPitch + (ix << 1) + ix;
-
- // If not mask_color then write the pixel
-
- if ((*(DWORD *)s & 0xffffff) != (DWORD)mask_color)
- *(WORD *)d = *(WORD *)s, d[2] = s[2];
- }
-
- // Update (x,y)
-
- x += dx_du;
- y += dy_du;
- }
-
- // Update the destination pointer to the next scanline
-
- d += destsurf.lPitch - (w << 1) - w;
-
- // (sx,sy) is moved one scanline
-
- sx += dx_dv;
- sy += dy_dv;
- }
-
- // Unlock surfaces
-
- src->Unlock(0);
- dest->Unlock(destrect);
- }
-
- void rotated_blit32(LPDIRECTDRAWSURFACE4 dest, RECT *destrect, LPDIRECTDRAWSURFACE4 src, int mx, int my, fix angle, fix scale)
- {
- // Define: (x,y) is a point in the source surface,
- // (u,v) is a point in the destination surface,
- // (0,0) corresponds to the center of the image in both surfaces.
- //
- // A point in the source surface is then given as:
- //
- // (x,y) = 1/scale * ((cos angle, sin angle), (-sin angle, cos angle)) (u,v)
-
- DDSURFACEDESC2 destsurf, srcsurf;
- BYTE *d, *s;
-
- ASSERT(scale != (fix)0);
-
- // Lock surfaces
-
- srcsurf.dwSize = sizeof(srcsurf);
-
- while (!draw_ok(src->Lock(0, &srcsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- destsurf.dwSize = sizeof(destsurf);
-
- while (!draw_ok(dest->Lock(destrect, &destsurf, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0)));
-
- // Get destination pointer
-
- d = (BYTE *)destsurf.lpSurface;
-
- // Get size of area to write
-
- int w = destrect->right - destrect->left,
- h = destrect->bottom - destrect->top;
-
- // Compute some frequently used variables
-
- fix cos_angle_over_scale = cos(angle) / scale,
- sin_angle_over_scale = sin(angle) / scale;
-
- // Compute (dx,dy) for (du,dv)=(1,0)
-
- #define dx_du cos_angle_over_scale
- #define dy_du -sin_angle_over_scale
-
- // Compute (dx,dy) for (du,dv)=(0,1)
-
- #define dx_dv sin_angle_over_scale
- #define dy_dv cos_angle_over_scale
-
- // Compute the first pixel in the destination surface (su, sv)
-
- int su = destrect->left - mx,
- sv = destrect->top - my;
-
- // Compute the first pixel in the source surface (sx, sy)
-
- fix sx = cos_angle_over_scale * su + sin_angle_over_scale * sv,
- sy = cos_angle_over_scale * sv - sin_angle_over_scale * su;
-
- // Transform to the source surface coordinates
-
- sx += srcsurf.dwWidth / 2;
- sy += srcsurf.dwHeight / 2;
-
- // Do the blit
-
- for (int v = 0; v < h; v++)
- {
- // (x,y) is the current pixel that has to be copied
-
- fix x = sx,
- y = sy;
-
- for (int u = 0; u < w; u++, d += 4)
- {
- // (ix,iy) is the integer location of the current pixel
-
- int ix = (int)x, iy = (int)y;
-
- // Check if (ix,iy) is in the image
-
- if (ix >= 0 && ix < (int)srcsurf.dwWidth && iy >= 0 && iy < (int)srcsurf.dwHeight)
- {
- // Compute the pixels location in memory
-
- s = ((BYTE *)srcsurf.lpSurface) + iy * srcsurf.lPitch + (ix << 2);
-
- // If not mask_color then write the pixel
-
- if (*(DWORD *)s != (DWORD)mask_color)
- *(DWORD *)d = *(DWORD *)s;
- }
-
- // Update (x,y)
-
- x += dx_du;
- y += dy_du;
- }
-
- // Update the destination pointer to the next scanline
-
- d += destsurf.lPitch - (w << 2);
-
- // (sx,sy) is moved one scanline
-
- sx += dx_dv;
- sy += dy_dv;
- }
-
- // Unlock surfaces
-
- src->Unlock(0);
- dest->Unlock(destrect);
- }
-